7.3 网络中的网络(NiN)

要点
  • NiN 用来替代全连接层,最后的通道数就是输出类别数,现在不常用,但影响了[[7.4 含并行连结的网络(GoogLeNet)]]
  • 主要作用:显著减少参数个数,防止过拟合
  • 相对于 VGG、AlexNet 这种包含全连接层的网络相比,收敛速度慢,往往需要多个 epoch

7.2 使用块的网络(VGG)7.1 深度卷积神经网络(AlexNet)这些网络最后都有全连接层,占绝大部分参数:

网络中的网络NiN)通过减少全连接层来减少这些参数个数,而且可以有效防止过拟合

1. NiN 块

一个卷积层后面跟两个 1 x 1 的卷积层,这些 1 x 1 卷积不会改变图像大小,只会改变通道数
7.3 网络中的网络(NiN).png|center|300 NiN 块示意图,1x 1 卷积层通道数保持一致
具体实现:

import torch
from torch import nn
from d2l import torch as d2l

def nin_block(in_channels, out_channels, kernel_size, strides, padding):
	# in_channels 是第一个卷积层输入通道大小,out_channels 是 1x1卷积输出通道
    return nn.Sequential(
        nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding),
        nn.ReLU(),
        nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU(),
        nn.Conv2d(out_channels, out_channels, kernel_size=1), nn.ReLU())

1 x 1 的卷积层作用是用来替代全连接层:

6.4 多输入多输出通道-3.png|center|500 1×1 卷积层示意图,不识别空间模式,只是融合通道,方便升维降维
上图输入通道为 3,输出通道为 2,把空间位置打散,等价于输入形状为 9×3 的矩阵,权重为 2×3 的矩阵(参考 4.2 多层感知机的从零开始实现#^6ec5de):
6.4 多输入多输出通道-4.png|center|300 1×1 卷积层等价于一个批的大小为 9 的全连接层

2. NiN 架构

交替使用 NiN 块和步幅为 2 的最大池化层,逐步减少图片尺寸,增大通道数,最后使用全局平均池化层得到输出:
7.3 网络中的网络(NiN)-1.png|center|500

net = nn.Sequential(
	# 输入是1,还是灰度图
    nin_block(1, 96, kernel_size=11, strides=4, padding=0),
    nn.MaxPool2d(3, stride=2),
    nin_block(96, 256, kernel_size=5, strides=1, padding=2),
    nn.MaxPool2d(3, stride=2),
    nin_block(256, 384, kernel_size=3, strides=1, padding=1),
    nn.MaxPool2d(3, stride=2),
    nn.Dropout(0.5),
    # 标签类别数是10
    nin_block(384, 10, kernel_size=3, strides=1, padding=1),
    nn.AdaptiveAvgPool2d((1, 1)),
    # 将四维的输出转成二维的输出,其形状为(批量大小,10)
    nn.Flatten())
X = torch.rand(size=(1, 1, 224, 224))
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__,'output shape:\t', X.shape)
Sequential output shape:     torch.Size([1, 96, 54, 54])
MaxPool2d output shape:      torch.Size([1, 96, 26, 26])
Sequential output shape:     torch.Size([1, 256, 26, 26])
MaxPool2d output shape:      torch.Size([1, 256, 12, 12])
Sequential output shape:     torch.Size([1, 384, 12, 12])
MaxPool2d output shape:      torch.Size([1, 384, 5, 5])
Dropout output shape:        torch.Size([1, 384, 5, 5])
Sequential output shape:     torch.Size([1, 10, 5, 5])
AdaptiveAvgPool2d output shape:      torch.Size([1, 10, 1, 1])
Flatten output shape:        torch.Size([1, 10])
  • 经过第一层后张量大小 (224-11+4)/4 = 54 (向下取整,参考[[6.3 填充和步幅]])
  • 最后的通道数表示分类的个数,AdaptiveAvgPool2d 把 5x5 的图像转化为 1x1 用作分类
  • AdaptiveAvgPool2d的参数就是输出图片大小,会自动计算池化窗口的大小和步长,以便于输出特征图的大小与预设的目标输出大小相匹配
  • 后面还有softmax 转化为概率,这个函数写在 训练函数里了([[6.6 卷积神经网络(LeNet)#^f57180]] 的 CrossEntropyLoss 里)

3. 训练

lr, num_epochs, batch_size = 0.1, 10, 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
loss 0.563, train acc 0.786, test acc 0.790
3087.6 examples/sec on cuda:0

7.3 网络中的网络(NiN)-2.png|center|300

参考文献



© 2023 yanghn. All rights reserved. Powered by Obsidian